package dm71.espil.activities.bomberman;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import dm71.espil.AccelerometerListener;
import dm71.espil.AccelerometerManager;
import dm71.espil.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.Toast;
import android.view.SurfaceHolder.Callback;
import android.view.animation.ScaleAnimation;

/**
 * TODO Put here a description of what this class does.
 * 
 * @author Moulde. Created Dec 21, 2011.
 */
public class BombermanActivity extends Activity implements
		AccelerometerListener, OnClickListener
{
	MySurfaceView surfaceBomb;
	GameLoop gameLoop;
	BitmapDrawable bombImage;
	BitmapDrawable boomImage;
	BitmapDrawable bombBackground;
	Random random;

	private Paint textPaint;

	float shaking = 0f;

	boolean IsExploded;
	Vibrator vibrator;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		// setContentView(R.layout.bombermanplayscreen);

		int bombRes_id = getResources().getIdentifier("tntbig", "drawable",
				getPackageName());
		bombImage = (BitmapDrawable) getResources().getDrawable(bombRes_id);

		int boomRes_id = getResources().getIdentifier("boom", "drawable",
				getPackageName());
		boomImage = (BitmapDrawable) getResources().getDrawable(boomRes_id);

		int bombBackgroundRes_id = getResources().getIdentifier(
				"bombbackground", "drawable", getPackageName());
		bombBackground = (BitmapDrawable) getResources().getDrawable(
				bombBackgroundRes_id);

		surfaceBomb = new MySurfaceView(this);
		setContentView(surfaceBomb, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

		surfaceBomb.setFocusable(true);
		surfaceBomb.setOnClickListener(this);

		textPaint = new Paint();
		textPaint.setColor(Color.WHITE);

		AccelerometerManager.SetContext(this);
		AccelerometerManager.StartListening(this);

		vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

		random = new Random();
		IsExploded = false;

		super.onCreate(savedInstanceState);
	}

	@Override
	protected void onDestroy()
	{
		super.onDestroy();

		try
		{
			this.gameLoop.safeStop();
		} 
		finally
		{
			this.gameLoop = null;
		}
	}

	@Override
	protected void onPause()
	{
		// TODO Auto-generated method stub.
		super.onPause();
	}

	@Override
	protected void onResume()
	{
		// TODO Auto-generated method stub.
		super.onResume();
	}

	private class GameLoop extends Thread
	{
		private volatile boolean running = true;

		@Override
		public void run()
		{
			while (running)
			{
				try
				{
					Thread.sleep(16);
					surfaceBomb.Update();
					surfaceBomb.Draw();
				} catch (InterruptedException exception)
				{
					// TODO Auto-generated catch-block stub.
					exception.printStackTrace();
					running = false;
				}
			}
		}

		public void safeStop()
		{
			running = false;
			interrupt();
		}
	}

	private class MySurfaceView extends SurfaceView implements Callback
	{
		private SurfaceHolder holder;

		public MySurfaceView(Context context)
		{
			super(context);
			getHolder().addCallback(this);
			this.holder = getHolder();
			this.holder.setFormat(PixelFormat.RGBA_8888);
		}

		public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
				int arg3)
		{
			// TODO Auto-generated method stub.
		}

		public void surfaceCreated(SurfaceHolder arg0)
		{
			BombermanActivity.this.gameLoop = new GameLoop();
			BombermanActivity.this.gameLoop.start();
		}

		public void surfaceDestroyed(SurfaceHolder arg0)
		{
			try
			{
				gameLoop.safeStop();
			} finally
			{
				gameLoop = null;
			}
		}

		public synchronized void Draw()
		{
			Canvas c = null;

			try
			{
				c = holder.lockCanvas();
				if (c != null)
				{
					DoDraw(c);
				}
			} catch (Exception e)
			{
				e.printStackTrace();
			} finally
			{
				if (c != null)
				{
					holder.unlockCanvasAndPost(c);
				}
			}
		}

		float x, y;
		float currentScale = 1f;
		float scaleChangeSpeed = 0.02f;

		float minScale = 1;
		float maxScale = 1.2f;

		float targetScale = maxScale;

		public synchronized void DoDraw(Canvas c)
		{
			int width = c.getWidth();
			int height = c.getHeight();

			float centerX = width / 2;
			float centerY = height / 2;

			c.drawBitmap(bombBackground.getBitmap(), 0, 0, null);

			float imageWidth = (bombImage.getBitmap().getWidth() * this.currentScale);
			float imageHeight = (bombImage.getBitmap().getHeight() * this.currentScale);

			x = centerX - imageWidth / 2;
			y = centerY - imageHeight / 2;

			RectF dest = new RectF(centerX - imageWidth / 2, centerY
					- imageHeight / 2, centerX + imageWidth / 2, centerY
					+ imageHeight / 2);

			if (!IsExploded)
			{
				c.drawBitmap(bombImage.getBitmap(), null, dest, null);
			} else
			{
				c.drawBitmap(boomImage.getBitmap(), x, y, null);
			}
		}

		private synchronized void Update()
		{
			// Clamp
			if (targetScale > maxScale)
			{
				targetScale = maxScale;
			} else if (targetScale < minScale)
			{
				targetScale = minScale;
			}

			if (IsExploded)
				return;

			// Interpolate
			if (Math.abs(currentScale - targetScale) < scaleChangeSpeed)
			{
				currentScale = targetScale;
				if (targetScale == minScale)
				{
					targetScale = maxScale;
				} else
				{
					targetScale = minScale;
				}
			} else if (currentScale > targetScale)
			{
				currentScale -= scaleChangeSpeed;
			} else if (currentScale < targetScale)
			{
				currentScale += scaleChangeSpeed;
			}
		}

		public void Explode()
		{
			this.currentScale = minScale;
		}
	}

	public void onAccelerationChanged(float x, float y, float z)
	{
		// TODO Auto-generated method stub.

	}

	public void onShake(float force)
	{
		Explode();
	}

	public void Explode()
	{
		Toast.makeText(this, "BOOM!", 1000).show();
		surfaceBomb.Explode();
		vibrator.vibrate(500);
		IsExploded = true;
	}

	public void onClick(View v)
	{
		if (IsExploded)
		{
			IsExploded = false;
		}
	}
}
